package com.education.platform.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.education.platform.dto.order.AdminOrderQueryDTO;
import com.education.platform.dto.order.CreateOrderDTO;
import com.education.platform.entity.Order;
import com.education.platform.entity.User;
import com.education.platform.entity.UserProfile;
import com.education.platform.exception.BusinessException;
import com.education.platform.mapper.OrderMapper;
import com.education.platform.mapper.UserMapper;
import com.education.platform.mapper.UserProfileMapper;
import com.education.platform.service.OrderService;
import com.education.platform.common.ResultCode;
import com.education.platform.vo.order.OrderVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl implements OrderService {

    private final OrderMapper orderMapper;
    private final UserMapper userMapper;
    private final UserProfileMapper userProfileMapper;

    @Override
    @Transactional
    public OrderVO createOrder(CreateOrderDTO dto) {
        Long parentId = StpUtil.getLoginIdAsLong();

        // 验证教员是否存在
        User teacher = userMapper.selectById(dto.getTeacherId());
        if (teacher == null || !teacher.getRoles().contains("TEACHER")) {
            throw new BusinessException("教员不存在");
        }

        // 获取教员资料
        UserProfile teacherProfile = userProfileMapper.selectOne(
            new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, dto.getTeacherId())
        );

        if (teacherProfile == null || teacherProfile.getHourlyRate() == null) {
            throw new BusinessException("教员资料不完整");
        }

        // 验证线下授课必须填写地址
        if ("OFFLINE".equals(dto.getTeachingType()) && StrUtil.isBlank(dto.getAddress())) {
            throw new BusinessException("线下授课必须填写上课地址");
        }

        // 创建订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo());
        order.setParentId(parentId);
        order.setTeacherId(dto.getTeacherId());
        order.setSubject(dto.getSubject());
        order.setGrade(dto.getGrade());
        order.setTeachingType(dto.getTeachingType());
        order.setTotalHours(dto.getTotalHours());
        order.setCompletedHours(0);
        order.setHourlyRate(teacherProfile.getHourlyRate());
        
        // 计算订单金额
        BigDecimal totalAmount = teacherProfile.getHourlyRate()
            .multiply(BigDecimal.valueOf(dto.getTotalHours()));
        order.setTotalAmount(totalAmount);
        order.setPaidAmount(BigDecimal.ZERO);
        
        // 计算平台手续费（10%）
        BigDecimal platformFee = totalAmount.multiply(BigDecimal.valueOf(0.1));
        order.setPlatformFee(platformFee);
        order.setTeacherIncome(totalAmount.subtract(platformFee));
        
        order.setStatus("CREATED");
        order.setStartDate(dto.getStartDate());
        order.setEndDate(dto.getEndDate());
        order.setAddress(dto.getAddress());
        order.setRequirements(dto.getRequirements());
        
        // 保存时间安排
        if (dto.getSchedule() != null && !dto.getSchedule().isEmpty()) {
            order.setSchedule(JSONUtil.toJsonStr(dto.getSchedule()));
        }

        orderMapper.insert(order);

        log.info("订单创建成功: orderNo={}, parentId={}, teacherId={}", 
            order.getOrderNo(), parentId, dto.getTeacherId());

        return convertToVO(order, teacher, teacherProfile);
    }

    @Override
    public Map<String, Object> getMyOrders(Integer page, Integer size, String status) {
        Long userId = StpUtil.getLoginIdAsLong();

        Page<Order> pageObj = new Page<>(page, size);
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        
        // 查询当前用户作为家长或教员的订单
        wrapper.and(w -> w.eq(Order::getParentId, userId).or().eq(Order::getTeacherId, userId));
        
        // 状态筛选
        if (StrUtil.isNotBlank(status)) {
            wrapper.eq(Order::getStatus, status);
        }
        
        wrapper.orderByDesc(Order::getCreatedAt);

        Page<Order> orderPage = orderMapper.selectPage(pageObj, wrapper);
        List<Order> orders = orderPage.getRecords();

        // 批量获取用户信息
        Set<Long> userIds = new HashSet<>();
        orders.forEach(order -> {
            userIds.add(order.getParentId());
            if (order.getTeacherId() != null) {
                userIds.add(order.getTeacherId());
            }
        });

        Map<Long, User> userMap = new HashMap<>();
        Map<Long, UserProfile> profileMap = new HashMap<>();
        
        if (!userIds.isEmpty()) {
            List<User> users = userMapper.selectBatchIds(userIds);
            users.forEach(user -> userMap.put(user.getId(), user));

            List<UserProfile> profiles = userProfileMapper.selectList(
                new LambdaQueryWrapper<UserProfile>().in(UserProfile::getUserId, userIds)
            );
            profiles.forEach(profile -> profileMap.put(profile.getUserId(), profile));
        }

        // 转换为VO
        List<OrderVO> orderVOList = orders.stream().map(order -> {
            User teacher = userMap.get(order.getTeacherId());
            UserProfile profile = profileMap.get(order.getTeacherId());
            return convertToVO(order, teacher, profile);
        }).collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("list", orderVOList);
        result.put("total", orderPage.getTotal());
        result.put("page", page);
        result.put("size", size);
        result.put("pages", orderPage.getPages());

        return result;
    }

    @Override
    public OrderVO getOrderDetail(Long id) {
        Long userId = StpUtil.getLoginIdAsLong();

        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        // 验证权限：只能查看自己的订单
        if (!order.getParentId().equals(userId) && 
            (order.getTeacherId() == null || !order.getTeacherId().equals(userId))) {
            throw new BusinessException("无权查看该订单");
        }

        User teacher = null;
        UserProfile profile = null;
        
        if (order.getTeacherId() != null) {
            teacher = userMapper.selectById(order.getTeacherId());
            profile = userProfileMapper.selectOne(
                new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, order.getTeacherId())
            );
        }

        OrderVO vo = convertToVO(order, teacher, profile);
        
        log.info("查询订单详情成功: orderId={}, userId={}", id, userId);
        
        return vo;
    }

    @Override
    @Transactional
    public void cancelOrder(Long id, String reason) {
        Long userId = StpUtil.getLoginIdAsLong();

        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        // 验证权限
        if (!order.getParentId().equals(userId)) {
            throw new BusinessException("无权取消该订单");
        }

        // 只有未支付的订单才能取消
        if (!"CREATED".equals(order.getStatus())) {
            throw new BusinessException("该订单无法取消");
        }

        order.setStatus("CANCELLED");
        order.setCancelReason(reason);
        orderMapper.updateById(order);

        log.info("订单取消成功: orderId={}, userId={}, reason={}", id, userId, reason);
    }

    @Override
    @Transactional
    public OrderVO payOrder(Long id) {
        Long userId = StpUtil.getLoginIdAsLong();

        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        // 验证权限：只有家长可以支付订单
        if (!order.getParentId().equals(userId)) {
            throw new BusinessException("无权支付该订单");
        }

        // 验证订单状态：只有待支付的订单才能支付
        if (!"CREATED".equals(order.getStatus())) {
            throw new BusinessException("该订单无法支付");
        }

        // 更新订单状态为已支付
        order.setStatus("PAID");
        order.setPaidAmount(order.getTotalAmount());
        orderMapper.updateById(order);

        log.info("订单支付成功: orderId={}, userId={}, amount={}", 
            id, userId, order.getTotalAmount());

        // 返回更新后的订单信息
        User teacher = null;
        UserProfile profile = null;
        
        if (order.getTeacherId() != null) {
            teacher = userMapper.selectById(order.getTeacherId());
            profile = userProfileMapper.selectOne(
                new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, order.getTeacherId())
            );
        }

        return convertToVO(order, teacher, profile);
    }

    @Override
    public Map<String, Object> adminGetOrders(AdminOrderQueryDTO queryDTO) {
        Page<Order> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();

        // 订单号查询
        if (StrUtil.isNotBlank(queryDTO.getOrderNo())) {
            wrapper.like(Order::getOrderNo, queryDTO.getOrderNo());
        }

        // 家长ID查询
        if (queryDTO.getParentId() != null) {
            wrapper.eq(Order::getParentId, queryDTO.getParentId());
        }

        // 教员ID查询
        if (queryDTO.getTeacherId() != null) {
            wrapper.eq(Order::getTeacherId, queryDTO.getTeacherId());
        }

        // 科目查询
        if (StrUtil.isNotBlank(queryDTO.getSubject())) {
            wrapper.like(Order::getSubject, queryDTO.getSubject());
        }

        // 状态查询
        if (StrUtil.isNotBlank(queryDTO.getStatus())) {
            wrapper.eq(Order::getStatus, queryDTO.getStatus());
        }

        // 日期范围查询
        if (StrUtil.isNotBlank(queryDTO.getStartDate())) {
            LocalDate startDate = LocalDate.parse(queryDTO.getStartDate());
            wrapper.ge(Order::getCreatedAt, startDate.atStartOfDay());
        }
        if (StrUtil.isNotBlank(queryDTO.getEndDate())) {
            LocalDate endDate = LocalDate.parse(queryDTO.getEndDate());
            wrapper.le(Order::getCreatedAt, endDate.atTime(23, 59, 59));
        }

        wrapper.orderByDesc(Order::getCreatedAt);

        Page<Order> orderPage = orderMapper.selectPage(page, wrapper);
        List<Order> orders = orderPage.getRecords();

        // 批量获取用户信息
        Set<Long> userIds = new HashSet<>();
        orders.forEach(order -> {
            userIds.add(order.getParentId());
            if (order.getTeacherId() != null) {
                userIds.add(order.getTeacherId());
            }
        });

        Map<Long, User> userMap = new HashMap<>();
        Map<Long, UserProfile> profileMap = new HashMap<>();

        if (!userIds.isEmpty()) {
            List<User> users = userMapper.selectBatchIds(userIds);
            users.forEach(user -> userMap.put(user.getId(), user));

            List<UserProfile> profiles = userProfileMapper.selectList(
                new LambdaQueryWrapper<UserProfile>().in(UserProfile::getUserId, userIds)
            );
            profiles.forEach(profile -> profileMap.put(profile.getUserId(), profile));
        }

        // 转换为VO，添加家长信息
        List<OrderVO> orderVOList = orders.stream().map(order -> {
            User teacher = userMap.get(order.getTeacherId());
            UserProfile teacherProfile = profileMap.get(order.getTeacherId());
            User parent = userMap.get(order.getParentId());
            UserProfile parentProfile = profileMap.get(order.getParentId());

            OrderVO vo = convertToVO(order, teacher, teacherProfile);

            // 设置家长信息
            if (parent != null) {
                vo.setParentName(parentProfile != null && StrUtil.isNotBlank(parentProfile.getRealName())
                    ? parentProfile.getRealName() : parent.getUsername());
            }

            return vo;
        }).collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("list", orderVOList);
        result.put("total", orderPage.getTotal());
        result.put("page", queryDTO.getPage());
        result.put("size", queryDTO.getSize());
        result.put("pages", orderPage.getPages());

        return result;
    }

    @Override
    @Transactional
    public void adminUpdateOrderStatus(Long id, String status, String remark) {
        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        String oldStatus = order.getStatus();
        order.setStatus(status);
        orderMapper.updateById(order);

        log.info("管理员更新订单状态: orderId={}, oldStatus={}, newStatus={}, remark={}",
            id, oldStatus, status, remark);
    }

    @Override
    @Transactional
    public void adminDeleteOrder(Long id) {
        Order order = orderMapper.selectById(id);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        orderMapper.deleteById(id);

        log.info("管理员删除订单: orderId={}", id);
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.valueOf((int) (Math.random() * 10000));
        return "ORD" + timestamp + String.format("%04d", Integer.parseInt(random));
    }

    /**
     * 转换为VO
     */
    private OrderVO convertToVO(Order order, User teacher, UserProfile profile) {
        OrderVO vo = new OrderVO();
        BeanUtils.copyProperties(order, vo);

        if (teacher != null) {
            vo.setTeacherName(profile != null && StrUtil.isNotBlank(profile.getRealName()) 
                ? profile.getRealName() : teacher.getUsername());
            vo.setTeacherAvatar(teacher.getAvatarUrl());
        } else {
            vo.setTeacherName("待分配");
            vo.setTeacherAvatar("");
        }

        // 设置状态文本
        vo.setStatusText(getStatusText(order.getStatus()));
        
        // 确保金额字段不为null
        if (vo.getTotalAmount() == null) {
            vo.setTotalAmount(BigDecimal.ZERO);
        }
        if (vo.getPaidAmount() == null) {
            vo.setPaidAmount(BigDecimal.ZERO);
        }
        if (vo.getHourlyRate() == null) {
            vo.setHourlyRate(BigDecimal.ZERO);
        }

        return vo;
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(String status) {
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("CREATED", "待支付");
        statusMap.put("PAID", "已支付");
        statusMap.put("ASSIGNED", "已分配");
        statusMap.put("IN_PROGRESS", "进行中");
        statusMap.put("COMPLETED", "已完成");
        statusMap.put("CANCELLED", "已取消");
        statusMap.put("REFUND_REQUESTED", "退款申请中");
        statusMap.put("REFUNDED", "已退款");
        statusMap.put("DISPUTE", "争议中");
        
        return statusMap.getOrDefault(status, status);
    }
}

